iT邦幫忙

2023 iThome 鐵人賽

DAY 26
0
自我挑戰組

30天開啟.NET後端工程師的旅程系列 第 26

Day26 使用Dapper實現ASP.NET Core Web API中的CRUD操作 (part 1)

  • 分享至 

  • xImage
  •  

前言

最初在學習C#的時候,針對EntityFramework的部分算做的蠻順手的了,但在查詢大量資料的時候就遇到,自己在SSMS寫指令碼查詢出來的速度比較快速,但到了自己建置出來的網站在查找資料速度就會變得比較慢,找尋其他解法的過程中才去了解到Dapper的技術。

在Day 17的時候有介紹使用ORM的內容,常用的除了當時使用的是EntityFramework,再來另一個就是這次的小專案要使用Dapper的方式。
這次還要結合Day16簡述資料庫的SQL Server指令碼(會需要對簡易的SQL Server指令碼查詢基礎了解喔!)。


前置作業跟Day24一樣,使用同一個資料庫,開頭一樣是先創建一個新的檔案(使用ASP.NET Core Web API的專案),使用Migration建立資料,以及appsettings.json裡面創建好的ConnectionStrings,來去連接資料庫。
如果不清楚的話可以參考前面這幾天的步驟建立。
Day17 使用.NET Core 建立簡單的CRUD (part 1)
Day18 使用.NET Core 建立簡單的CRUD (part 2 資料庫建立完成)

那我們這次的ORM不使用EntityFramework,改成使用Dapper,在使用前當然就簡單先來介紹。

什麼是Dapper??

Dapper 是 .NET 開發平台的 ORM (Object Relationship Mapping) 套件,用於資料庫存取時提供物件關聯對應功能,取出資料時將資料轉換成強型別的物件,使開發過程中更容易操作、使用,其撰寫方式與 ADO.NET 寫法相似。

Dapper 是一個輕量級的物件關聯映射(ORM)工具,簡化了在.NET應用程式中執行資料庫操作的過程。以下是關於Dapper的詳細介紹:

  1. 輕量級和高效:Dapper的主要特點之一是它的輕量級性質。相較於一些重量級的ORM工具,Dapper的程式碼庫非常小巧,不會增加應用程式的運行時負擔,也因為這樣使得Dapper非常高效,並適用於需要快速執行資料庫操作的場景。
  2. 對應程式功能:Dapper提供對應程式功能,用於將.NET物件與資料庫表格中的資料進行映射。可以使用.NET物件來表示資料庫中的記錄,而不必手動撰寫冗長的資料庫查詢和映射程式碼。
  3. 簡化的參數化查詢:簡單地就將.NET物件的屬性與SQL陳述式的參數進行對應。可以輕鬆地執行參數化查詢,而不需要手動指定每個參數的值。
  4. 非同步支援:Dapper支援非同步程式設計,意思就是可以在應用程式中執行非同步的資料庫操作,藉此提高應用程式的效能和反應速度。
  5. 多資料庫支援:Dapper可以與多種不同的資料庫系統一起使用,包括SQL Server、MySQL、PostgreSQL等,這使得它成為跨不同資料庫平台的選擇。
  6. 開源:Dapper是一個開源項目,可以在GitHub上找到它的原始碼。這意味著您可以自由使用、修改和貢獻給這個工具。

Dapper 就像你在尋寶遊戲中使用放大鏡一樣,可以讓我們輕鬆地找到和使用我們需要的資料,而不需要花很多時間去尋找或翻閱整個書本(資料庫)。

安裝Dapper套件

可以使用NuGet套件管理器執行以下命令:

Install-Package Dapper

創建一個DapperRepository:

創建一個DapperRepository或資料存取類別,這個類別使用Dapper與資料庫互動實現CRUD(Create、Read、Update、Delete)操作的地方。

這裡要示範使用的DapperRepostiroy命名為**ArticleRepository**的類別,這個類別負責使用Dapper來執行與文章(Article)相關的資料庫操作。

下面是一個簡單的DapperRepository示例:

using System.Data; //這個命名空間包含用於資料存取的一般資料庫相關類別。
using System.Data.SqlClient; //這個命名空間包含用於SQL Server資料庫的相關資料庫相關類別。
using Dapper;

public class ArticleRepository
{
    private readonly string _connectionString;

    public ArticleRepository(string connectionString)
    {
        _connectionString = connectionString;
    }

		//GetAllArticlesAsync 從資料庫中擷取所有文章的清單,把結果以**IEnumerable<Article>**的形式返回
    public async Task<IEnumerable<Article>> GetAllArticlesAsync()
    {
        using IDbConnection dbConnection = new SqlConnection(_connectionString);
        dbConnection.Open();
        return await dbConnection.QueryAsync<Article>("SELECT * FROM Articles");
    }

		//根據文章的ID從資料庫中擷取一篇文章,以**Article**物件的形式返回。
    public async Task<Article> GetArticleByIdAsync(int id)
    {
        using IDbConnection dbConnection = new SqlConnection(_connectionString);
        dbConnection.Open();
        return await dbConnection.QueryFirstOrDefaultAsync<Article>("SELECT * FROM Articles WHERE Id = @Id", new { Id = id });
    }

		//用於將一篇新文章插入到資料庫中
    public async Task<int> InsertArticleAsync(Article article)
    {
        using IDbConnection dbConnection = new SqlConnection(_connectionString);
        dbConnection.Open();
        return await dbConnection.ExecuteAsync("INSERT INTO Articles (Title, Content) VALUES (@Title, @Content)", article);
    }

		//用於更新現有的文章
    public async Task<int> UpdateArticleAsync(Article article)
    {
        using IDbConnection dbConnection = new SqlConnection(_connectionString);
        dbConnection.Open();
        return await dbConnection.ExecuteAsync("UPDATE Articles SET Title = @Title, Content = @Content WHERE Id = @Id", article);
    }

		//根據文章的ID刪除資料庫中的一篇文章,。
    public async Task<int> DeleteArticleAsync(int id)
    {
        using IDbConnection dbConnection = new SqlConnection(_connectionString);
        dbConnection.Open();
        return await dbConnection.ExecuteAsync("DELETE FROM Articles WHERE Id = @Id", new { Id = id });
    }
}

ArticleRepository 類別定義:

public class ArticleRepository
{
    private readonly string _connectionString;

    public ArticleRepository(string connectionString)
    {
        _connectionString = connectionString;
    }
}
  • ArticleRepository 的這個類別,主要是負責處理文章相關的資料庫操作。
  • 在這個類別裡面有看到同樣名稱的,所以裡面同名的這個是建構函式,這個建構函式裡面接受一個連接字串 (connectionString) 作為傳入的參數,用於初始化 _connectionString 成員變數,這個連接字串用於連接到資料庫。
  • 方法定義:
    ArticleRepository 類別包含了以下5個非同步可以處理增刪查改的方法,都是public的公開方法,可以讓其他的方法呼叫的到,用於執行不同的資料庫操作:
  • 首先先解釋這5個方法裡面相同的部分。
    • using IDbConnection dbConnection = new SqlConnection(_connectionString);
      • 建立了一個資料庫連接對象 (IDbConnection),這是用來連接資料庫的通道。
      • 使用 _connectionString,這是在建構函式中傳遞的連接字串,來指定連接到哪個資料庫。
    • dbConnection.Open();
      • 這行程式碼打開了資料庫連接,讓我們可以開始與資料庫進行通訊。
  • GetAllArticlesAsync():這個方法就像我們在執行GET查詢動作的一樣,只是使用Dapper的**QueryAsync**方法執行SQL查詢,查詢結果映射成 Article 物件的集合,最後把這個集合作為結果返回給呼叫這個方法的程式碼。
  • GetArticleByIdAsync(int id):使用Dapper的**QueryFirstOrDefaultAsync**方法執行SQL查詢,同時也接受一個參數 id,以指定要擷取的文章ID。
    QueryFirstOrDefaultAsync 是 Dapper 中的一個方法,用於從資料庫中執行 SQL 查詢並返回結果中的第一個元素,如果找不到匹配的項目,則返回默認值或 null。
  • InsertArticleAsync(Article article):使用Dapper的**ExecuteAsync**方法執行SQL INSERT語句(在前面簡述資料庫的時候知道,這個Insert表示是要新增一筆資料),同時接受一個參數 article,代表要插入的文章物件。
    • await dbConnection.ExecuteAsync("INSERT INTO Articles (Title, Content) VALUES (@Title, @Content)", article):這是實際的資料庫操作。ExecuteAsync 方法用於執行 SQL 命令,並且是非同步的,所以不會阻塞主執行緒。
      • "INSERT INTO Articles (Title, Content) VALUES (@Title, @Content)":這是 SQL INSERT 陳述式,指示資料庫將一條新的紀錄插入到 "Articles" 資料表中。@Title@Content 是參數,它們對應到 article 物件中的屬性。在執行時,Dapper 將自動將 article 物件的屬性值映射到 SQL 命令中的參數,以確保安全性和正確性。
    • return await dbConnection.ExecuteAsync(...):執行 INSERT 命令。
  • UpdateArticleAsync(Article article):它使用Dapper的**ExecuteAsync**方法執行SQL UPDATE語句,同時接受一個參數 article,代表要更新的文章物件。
  • DeleteArticleAsync(int id):使用Dapper的**ExecuteAsync**方法執行SQL DELETE語句,同時接受一個參數 id,代表要刪除的文章ID。

挑戰第26天完成!!!!剩下4天了!!!


上一篇
Day25 使用ASP.NET Core Web API 修改及刪除資料
下一篇
Day27 使用Dapper實現ASP.NET Core Web API中的CRUD操作 (part 2 Controller 建立)
系列文
30天開啟.NET後端工程師的旅程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言